package tech.summerly.weather.component.activities

import android.arch.lifecycle.ViewModelProviders
import android.content.Intent
import android.os.Bundle
import android.support.design.widget.NavigationView
import android.support.v4.view.GravityCompat
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AppCompatActivity
import android.view.MenuItem
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import tech.summerly.weather.R
import tech.summerly.weather.component.fragments.EmptyCityPromptFragment
import tech.summerly.weather.component.fragments.WeatherTowerFragment
import tech.summerly.weather.component.viewmodel.UserRegionViewModel
import tech.summerly.weather.model.Region
import tech.summerly.weather.util.inTransaction
import tech.summerly.weather.util.observeFilterNull
import tech.summerly.weather.util.requestPermission

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {


    companion object {

        const val KEY_REGION = "region"

        private const val FRAGMENT_EMPTY_CITIES_PROMPT = "empty_city_prompt_fragment"
    }

    private var currentRegion: Region? = null

    private val cityListViewModel by lazy {
        ViewModelProviders.of(this, UserRegionViewModel).get(UserRegionViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
        subscribeUI()
    }

    private fun initView() {
        val toggle = ActionBarDrawerToggle(
                this, drawerLayout, null, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
        drawerLayout.addDrawerListener(toggle)
        toggle.syncState()
        navView.setNavigationItemSelectedListener(this)
    }

    private fun subscribeUI() {
        cityListViewModel.regionList.observeFilterNull(this) { userRegionList ->
            if (userRegionList.isEmpty()) {
                setEmptyCityPrompt(true)
            } else {
                setEmptyCityPrompt(false)
            }
            val regionList = userRegionList.map { it.region }
            if (regionList.none { it == currentRegion }) {
                showWeather(regionList.getOrNull(0))
            }
            refreshNavigationDrawerMenu(regionList)
        }
    }

    private fun showWeather(region: Region?) {
        currentRegion = region
        if (region != null) {
            var fragment = supportFragmentManager.findFragmentByTag(WeatherTowerFragment.TAG) as? WeatherTowerFragment
            if (fragment == null) {
                fragment = WeatherTowerFragment()
                supportFragmentManager.inTransaction {
                    add(R.id.contentContainer, fragment, WeatherTowerFragment.TAG)
                }
            }
            fragment.setRegion(region)
        }
    }

    private fun setEmptyCityPrompt(show: Boolean) = supportFragmentManager.inTransaction {
        val fragment = supportFragmentManager.findFragmentByTag(FRAGMENT_EMPTY_CITIES_PROMPT)
        if (show) {
            if (fragment != null && fragment.isAdded) {
                return@inTransaction
            }
            replace(R.id.contentContainer, EmptyCityPromptFragment.newInstance(), FRAGMENT_EMPTY_CITIES_PROMPT)
        } else {
            fragment?.let {
                remove(it)
            }
        }
    }

    //刷新导航抽屉的城市
    private fun refreshNavigationDrawerMenu(regions: List<Region>?) {
        val menu1 = navView.menu.findItem(R.id.nav_location_1).setVisible(false)
        val menu2 = navView.menu.findItem(R.id.nav_location_2).setVisible(false)
        val menu3 = navView.menu.findItem(R.id.nav_location_3).setVisible(false)

        regions ?: return
        val size = regions.size

        val showMenu = { menu: MenuItem, region: Region ->
            menu.setVisible(true).setTitle(region.name)
            if (region == currentRegion) {
                menu.isChecked = true
            }
        }
        if (size >= 1) {
            showMenu(menu1, regions[0])
        }
        if (size >= 2) {
            showMenu(menu2, regions[1])
        }
        if (size >= 3) {
            showMenu(menu3, regions[2])
        }
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        val city = intent.getParcelableExtra<Region>(KEY_REGION) ?: return
        showWeather(city)
    }

    override fun onStart() {
        super.onStart()
        checkPreferenceChange()
    }

    override fun onBackPressed() {
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
            drawerLayout.closeDrawer(GravityCompat.START)
            return
        }
        super.onBackPressed()
    }

    private fun checkPreferenceChange() {

    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.nav_location_1 -> cityListViewModel.regionList.value?.getOrNull(0)?.let { showWeather(it.region) }
            R.id.nav_location_2 -> cityListViewModel.regionList.value?.getOrNull(1)?.let { showWeather(it.region) }
            R.id.nav_location_3 -> cityListViewModel.regionList.value?.getOrNull(2)?.let { showWeather(it.region) }
            R.id.nav_manage -> {
                startActivity(Intent(this, UserRegionManagerActivity::class.java))
            }
            R.id.nav_about -> {
                startActivity(Intent(this, AboutActivity::class.java))
            }
            R.id.nav_stream -> {
                launch(UI) {
                    val permission = requestPermission(android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO)
                    if (permission.all { it }) {
                        startActivity(Intent(this@MainActivity, StreamPushActivity::class.java))
                    } else {
                        tech.summerly.weather.util.toast("需要权限")
                    }
                }
            }
            R.id.nav_setting -> startActivity(Intent(this, SettingsActivity::class.java))
        }
        drawerLayout.closeDrawer(GravityCompat.START)
        return true
    }

}
